package com.caigou.task;

import com.caigou.bean.cms.entity.Article;
import com.caigou.bean.cms.entity.ArticleInformation;
import com.caigou.bean.cms.entity.ChannelData;
import com.caigou.bean.empire.entity.EmpireSyncArticleData;
import com.caigou.bean.vo.EsArticleMqVO;
import com.caigou.component.*;
import com.caigou.enums.Constant;
import com.caigou.service.ArticleInformationService;
import com.caigou.service.ArticleService;
import com.caigou.service.ChannelDataService;
import com.caigou.service.EmpireDataSyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
@EnableScheduling
public class EmpireDataSyncTask {

    @Resource
    private ChannelDataService channelDataService;
    @Resource
    private ArticleService articleService;

    @Resource
    private RedisComponent redisComponent;
    @Resource
    private EmpireDataSyncService empireDataSyncService;
    @Resource
    private ArticleInformationService articleInformationService;
    @Resource
    private EmpireDataSyncComponent empireDataSyncComponent;
    @Resource
    private HtmlDetailBuilderComponent htmlDetailBuilderComponent;
    @Resource
    private RabbitProducer rabbitProducer;
    @Resource
    private AmqpTemplate amqpTemplate;

    @Value("${domain}")
    private String domain;

    private final String empireDataSyncTime = "1607097600";// 数据同步时间节点（2020-12-05 00:00:00  ？？）

    /**
     * 每小时执行一次同步数据（旧数据）[第一版频道旧数据]目前数据已跑完可改为每小时100条SQL
     */
//    @Scheduled(cron = "0 */1 * * * ?")// 分钟
//    @Scheduled(cron = "0 0 0 * * ?")// 每晚0点执行针对旧数据的更新
//    @Scheduled(cron =  "0 0 0,3,21 * * ?")// 预设每晚21点、0点、3点各执行一次(第一批数据跑完之后可调整为0点跑一次)预计8-9天可将旧数据跑完
    @Scheduled(cron =  "0 0 0/1 * * ?")// 每5小时执行一次
    public void empireDataSync(){
        // 判别任务同步锁
        String key = "task:lock:empireDataSync";// 旧数据同步锁的key
        boolean lockFlag = redisComponent.setLock(key, 3000);
        if (!lockFlag){
            log.info("旧数据同步任务锁获取失败");
            return;
        }
        // 判别定时任务是否已经被关闭
        String empireDataSyncStatus = "empireDataSyncStatus";
        String status = redisComponent.get(empireDataSyncStatus);
        if (null != status && !status.equals("") && status.equals("0")) {
            log.info("旧数据任务已被关闭");
            return;
        }
        log.info("开始执行旧数据同步");
        int limit = 1000;
        // 判别上一次执行的时间节点
        String empireDataSyncLastTime = "empireDataSyncLastTime";
        String lastTime = redisComponent.get(empireDataSyncLastTime);
        log.info("获取到的上一次执行的数据："+lastTime);
        if (null == lastTime || lastTime.equals("")) lastTime = "0";
        // 获取当前需要执行的数据列表
        List<EmpireSyncArticleData> list = empireDataSyncService.loadEmpireSyncArticleDataByPlate(Long.valueOf(lastTime), Long.valueOf(empireDataSyncTime),limit);
        for (EmpireSyncArticleData info : list){
            empireDataSyncComponent.disposeData(info,0);
        }
        boolean releaseFlag = redisComponent.releaseLock(key);
        log.info("旧数据同步完成 释放锁"+releaseFlag);
    }

    /**
     * 每小时执行一次同步数据（新数据）[第一版频道新数据]目前数据已跑完可改为每小时100条SQL
     */
    @Scheduled(cron = "0 0 0/1 * * ?")// 小时
    public void empireNewDataSync(){
        // 判别任务同步锁
        String key = "task:lock:empireNewDataSync";// 旧数据同步锁的key
        boolean lockFlag = redisComponent.setLock(key, 3000);
        if (!lockFlag){
            log.info("新数据同步任务锁获取失败");
            return;
        }
        // 判断任务开启状态
        String empireNewDataSyncStatus = "empireNewDataSyncStatus";
        String status = redisComponent.get(empireNewDataSyncStatus);
        if (null != status && !status.equals("") && status.equals("0")) {
            log.info("新数据任务已被关闭");
            return;
        }
        log.info("开始执行新数据同步");
        int limit = 1000;
        // 判断上一次执行的条数
        String empireNewDataSyncLastTime = "empireNewDataSyncLastTime";
        String lastTime = redisComponent.get(empireNewDataSyncLastTime);
        log.info("获取到的上一次执行的数据："+lastTime);
        if (null == lastTime || lastTime.equals("")) lastTime = "0";
        // 获取数据进行同步处理
        List<EmpireSyncArticleData> list = empireDataSyncService.loadEmpireSyncArticleDataByPlate2(Long.valueOf(lastTime), Long.valueOf(empireDataSyncTime),limit);
        for (EmpireSyncArticleData info : list){
            empireDataSyncComponent.disposeData(info,1);
        }
        boolean releaseFlag = redisComponent.releaseLock(key);
        log.info("新数据同步完成 释放锁"+releaseFlag);
    }

    /**
     * 处理已生成文本中的空白符等
     */
//    @Scheduled(cron = "0 0 0/1 * * ?")// 小时
    public void processCompletedData(){
        // 判别任务同步锁
        String empireNewDataSync2TaskKey = "task:lock:processCompletedData";
        boolean lockFlag = redisComponent.setLock(empireNewDataSync2TaskKey, 3000);
        if (!lockFlag){ log.info("processCompletedData任务锁获取失败");return; }
        log.info("开始执行processCompletedData任务");
        int limit = 1000;
        // 判断上一次执行的条数
        String id = redisComponent.get("processCompletedDataLastId");
        log.info("empireNewDataSync2任务--获取到的上一次执行的数据："+id);
        if (null == id || id.equals("")) id = "0";
        // 获取数据进行同步处理
        List<ArticleInformation> list = articleInformationService.loadDisponseFinalDataList(id,limit);
        for (ArticleInformation info : list){
            String content = empireDataSyncComponent.disponseInfo(info.getArticleContent());
            articleInformationService.updateArticleInformationData(info.getArticleId(),content);
            ChannelData channelData = channelDataService.loadLastChannelData(info.getArticleId());
            if (null == channelData) {
                htmlDetailBuilderComponent.buildArticleHtml(info.getArticleId(), "999");
            } else {
                htmlDetailBuilderComponent.buildArticleHtml(info.getArticleId(), channelData.getPlateId());
            }
            redisComponent.set("processCompletedDataLastId", info.getArticleId());
        }
        boolean releaseFlag = redisComponent.releaseLock(empireNewDataSync2TaskKey);
        log.info("empireNewDataSync2任务完成 释放锁"+releaseFlag);
    }

    // 根据需求处理文章详情页
    @Scheduled(cron = "0 0 0/1 * * ?")// 小时
    public void disposeArticleDetail(){
        // 判别任务同步锁
        String disposeArticleDetailKey = "task:lock:disposeArticleDetail";
        boolean lockFlag = redisComponent.setLock(disposeArticleDetailKey, 3000);
        if (!lockFlag){ log.info("disposeArticleDetail任务锁获取失败");return; }
        log.info("开始执行disposeArticleDetail任务");
        int limit = 1000;
        // 判断上一次执行的条数
        List<Article> list = articleService.loadArticleDisposeList(limit);
        list.forEach(item -> {
            // 更新文章静态页(根据所属频道)
            ChannelData channelData = channelDataService.loadLastChannelData(item.getArticleId());
            if (null == channelData) {
                htmlDetailBuilderComponent.buildArticleHtml(item.getArticleId(), "999");
            } else {
                htmlDetailBuilderComponent.buildArticleHtml(item.getArticleId(), channelData.getPlateId());
            }
//            // 更新文章分享图
//            if (item.getArticleType() != 4 && item.getArticleType() != 14) {
//                String articleContent = articleService.loadArticlePreviewData(item.getArticleId());
//                Map<String, Object> map = new HashMap<>();
//                map.put("articleId", item.getArticleId());
//                map.put("articleContent", articleContent);
//                rabbitProducer.sendDefaultMessage(map);
//            }
            // 数据处理完成之后更新数据表中的处理状态（跑完）
            articleService.updateArticleDisposeStatus(item.getArticleId());
            // 修改任何一项文章内容，发送ESMQ消息
            amqpTemplate.convertAndSend(Constant.CMS_ARTICLE_QUEUE, Collections.singletonList(new EsArticleMqVO(item.getArticleId(), Constant.UPDATE_ARTICLE)));
        });
        boolean releaseFlag = redisComponent.releaseLock(disposeArticleDetailKey);
        log.info("disposeArticleDetail任务完成 释放锁"+releaseFlag);
    }
}
